package back;
import graph.MensajeFrame;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
/**
 * La Clase Juego permite almacenar informacion del juego actual
 * como el nivel, el nombre del jugador, etc.
 */


public class Juego {

	private Tablero tablero;
	private String jugador;
	private String nivel;
	private File[] niveles;
	private int nivelActual;
	private boolean JuegoTerminado=false;
	
	/**
	 * Constructor de la clase Juego.
	 * @param niveles array de File con los archivos contenidos en el
	 * directorio de niveles.
	 */
	
	public Juego(File[] niveles) {
		this.niveles = niveles;
		this.nivelActual=0;
	}
	
	/**
	 * Retorna el nivel actual.
	 * @return int nivelActual.
	 */
	
	public int nivel(){
		return nivelActual;
	}
	
	/**
	 * Retorna el siguiente archivo del directorio.
	 * 
	 * @return File siguiente archivo o null en caso de haber terminado la lista.
	 */
	
	public File siguienteNivel() {
		if(nivelActual < niveles.length) {
			File retorno = niveles[nivelActual];
			setNivelActual(nivelActual + 1);
			return retorno;
		} return null;
	}

	/**
	 * Setea el indice actual del nivel que se esta jugando.
	 * 
	 * @param int nivelActual indice del array de Files.
	 */
	
	public void setNivelActual(int nivelActual) {
		this.nivelActual = nivelActual;
	}
	
	/**
	 * Setea el nombre del nivel, se debe conocer al momento de guardar la partida
	 * o los puntos.
	 * 
	 * @param String nivel nombre del nivel.
	 */
	
	public void cambiaNivel(String nivel) {
		this.nivel = nivel;
	}
	
	/**
	 * Retorna el nombre del nivel.
	 * 
	 * @return String nombre del nivel.
	 */
	
	public String verNivel() {
		return nivel;
	}

	/**
	 * Setea el nombre del jugador, se debe conocer al momento de guardar la partida
	 * o los puntos.
	 * 
	 * @param String jugador nombre del jugador.
	 */
	
	public void cambiaJugador(String jugador) {
		this.jugador =jugador;
	}
	
	/**
	 * Retorna el nombre del jugador.
	 * 
	 * @return String nombre del jugador.
	 */
	
	public String verJugador() {
		return jugador;
	}
	
	/**
	 * Guarda la referencia al tablero del nivel actual.
	 * 
	 * @param Tablero tablero de juego del nivel actual.
	 */
	
	public void cambiaTablero(Tablero tablero) {
		this.tablero = tablero;
	}
	
	/**
	 * Retorna la referencia al tablero.
	 *  
	 * @return Tablero tablero del nivel actual.
	 */
	
	public Tablero getTablero() {
		return tablero;
	}
	
	
	/**
	 * Retorna una archivo con el nivel actual.
	 * @return File archivo con el nivel actual.
	 */

	public File getNivelActual(){
		return this.niveles[this.nivelActual];
	}
	
	
	/**
	 * Realiza un movimiento en la direccion recibida como parametro
	 * @param int direccion en la cual se va a realizar el movimiento
	 */

	
	public void hacerMov(int direccion){
		tablero.posibleMovida(direccion);
		if(tablero.tableroTerminado()){
			int puntos=calculaPuntos(tablero.getMovimientos());
			try {
				ArchivoPuntaje.guardarPuntajes(nivel, jugador, puntos);
			} catch (IOException e1) {}
			if(niveles.length > this.nivelActual +1){
				this.nivelActual++;
				try {
					reiniciarNivel();
				} catch (Exception e) {	}
			} else{
				JuegoTerminado=true;
			}
			return;
		}
		if(this.tablero.perdido()){
			try {
         		String mensaje = "Te has caido, se reiniciara el nivel actual.";
         		new MensajeFrame(mensaje);
				reiniciarNivel();
			} catch (Exception e) {}			
		}
	}
	
	/**
	 * Calcula el puntaje y lo retorna
	 * @param int movimientos hechos por el jugador
	 * @return int puntaje obtenido
	 */
	private int calculaPuntos(int movimientos) {
		if(movimientos>500)
			return 0;
		return 1000-movimientos;
	}

	
	/**
	 * Carga el tablero con el estado incial del nivel
 	 * @throws FileNotFoundException si no encontrara el archivo
	 * @throws IOException si hubiera error en la lectura o escritura.
	 */

	public void reiniciarNivel() throws FileNotFoundException, IOException {
		Archivos.cargarTablero(this, this.jugador,new BufferedReader(new FileReader(this.getNivelActual())),0);
	}
	
	/**
	 * Retorna verdadero si el juego esta terminado
	 * y falso en caso contrario
	 * @return boolean
	 */

	public boolean JuegoTerminado(){
		return JuegoTerminado;
	}
	
		
}

